package com.control;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.model.Node;
import com.model.Tree;
import com.view.optionpanel.ShowMessage;

public class MyTreeControl<T> {
	private final int DEFAULT_SIZE = 2;
	private int size;// 数组长度
	private int count;// 记录树有多少个节点
	private Object[] nodes;// 模拟树

	public MyTreeControl() {
		this.size = this.DEFAULT_SIZE;
		this.nodes = new Object[this.size];
		this.count = 0;
	}

	public MyTreeControl(Node<T> root) {
		this();
		this.count = 1;
		this.nodes[0] = root;
	}

	public MyTreeControl(Node<T> root, int size) {
		this.size = size;
		this.nodes = new Object[this.size];
		this.count = 1;
		this.nodes[0] = root;
	}

	@SuppressWarnings("rawtypes")
	public MyTreeControl(Tree tree) {
		this.size = tree.getSize();
		this.count = tree.getCount();
		this.nodes = tree.getNodes().toArray();
	}

	// 添加一个节点
	@SuppressWarnings("unchecked")
	public void add(Node<T> node) {
		for (int i = 0; i < this.size; i++) {
			if (this.nodes[i] == null) {
				nodes[i] = node;
				((Node<T>) nodes[i]).setMyself(i);
				break;
			}
		}
		this.count++;
	}

	public void check() {
		if (this.count >= this.size) {
			this.enlarge();
		}
	}

	// 添加一个节点，并指明父节点
	public boolean add(Node<T> node, Node<T> parent, int type) {
		if (parent.getType() == 0) {
			if(parent.getChildNodes().size()<8){
            if(checkName(parent.getChildNodes(), node.getData().toString())){
			this.check();
			int parentid = this.position(parent);
			node.setParent(parentid);
			node.setType(type);
			this.add(node);
			linkFather(parentid, node);
			return true;
            }else{
            	ShowMessage.error("名字不可以相同", null);
            	return false;
            }
			}
			else {
				ShowMessage.error("磁盘块区已满，无法新建！", null);
            	return false;
			}
		} else {
			ShowMessage.warning("文件不能添加文件", null);
			return false;
		}
	}

	public boolean checkName(List<Node<T>> children, String name) {// 判断
		int flag = 0;
		for (Node<T> node : children) {
			if (node.getData().toString().equals(name))
				flag = 1;
		}
		if (flag == 1)
			return false;
		else
			return true;
	}

	// 父节点与子节点关联
	@SuppressWarnings("unchecked")
	public void linkFather(int parent, Node<T> node) {
		((Node<T>) this.nodes[parent]).setChild(node);
	}

	// 删除节点及其子节点
	@SuppressWarnings("unchecked")
	public void removeNode(int id) {
		Node<T> node = (Node<T>) nodes[id];
		if (node.getChildNodes().size() == 0) {
			nodes[id] = null;
			this.count--;
		} else {
			List<Node<T>> removeQuene = getAllChildNodes(node);
			removeQuene.add(node);
			for (Node<T> t : removeQuene) {
				nodes[t.getMyself()] = null;
				//System.out.println("shanchu" + t.getData().toString());
				this.count--;
			}
		}
	}

	// 清除父节点中关于被删除子节点的信息
	public void killChild(int id) {
		Node<T> child = getNode(id);
		//System.out.println("删除儿子" + child.getData().toString());
		Node<T> father = getNode(child.getParent());
		father.getChildNodes().remove(child);
		nodes[father.getMyself()] = father;

	}
	
	@SuppressWarnings("unchecked")
	public void updateNode(Node<T> node){
		for(int i =0;i<nodes.length;i++){
			try {
				if(((Node<T>)nodes[i]).getMyself()==node.getMyself()){
					nodes[i] = node;
					break;
				}
			} catch (Exception e) {
				continue;
			}
		}
	}

	// 获取某节点下的所有子节点
	public List<Node<T>> getAllChildNodes(Node<T> node) {
		List<Node<T>> childNodes = new ArrayList<Node<T>>();
		childNodes.addAll(node.getChildNodes());
		for (Node<T> childNode : node.getChildNodes()) {
			if (childNode.getChildNodes().size() > 0) {
				childNodes.addAll(getAllChildNodes(childNode));
			}
		}
		return childNodes;

	}

	// 获取节点在数组的存储位置
	public int position(Node<T> node) {
		for (int i = 0; i < this.size; i++) {
			if (nodes[i] == node) {
				return i;
			}
		}
		return -1;
	}

	// 获取整棵树有多少节点
	public int getSize() {
		return this.count;
	}

	// 获取根节点
	@SuppressWarnings("unchecked")
	public Node<T> getRoot() {
		return (Node<T>) this.nodes[0];
	}

	// 获取根节点
	@SuppressWarnings("unchecked")
	public Node<T> getNode(int i) {
		return (Node<T>) this.nodes[i];
	}

	// 获取所以节点，以List形式返回
	@SuppressWarnings("unchecked")
	public List<Node<T>> getAllNodes() {
		List<Node<T>> list = new ArrayList<Node<T>>();
		for (int i = 0; i < this.size; i++) {
			if (this.nodes[i] != null) {
				list.add((Node<T>) nodes[i]);
			}
		}
		return list;
	}

	// 获取树的深度，只有根节点时为1
	@SuppressWarnings("unchecked")
	public int getDepth() {

		int max = 1;
		if (this.nodes[0] == null) {
			return 0;
		}

		for (int i = 0; i < this.count; i++) {
			int deep = 1;
			int location = ((Node<T>) (this.nodes[i])).getParent();
			while (location != -1 && this.nodes[location] != null) {
				location = ((Node<T>) (this.nodes[location])).getParent();
				deep++;
			}
			if (max < deep) {
				max = deep;
			}
		}
		return max;
	}

	// 扩大数组
	public void enlarge() {
		this.size = this.size + this.DEFAULT_SIZE;
		Object[] newNodes = new Object[this.size];
		newNodes = Arrays.copyOf(nodes, this.size);
		Arrays.fill(nodes, null);
		this.nodes = newNodes;
		//System.out.println("enlarge");
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public int getIdByPath(String path) {
		if ("磁盘目录".equals(path)) {
			return 0;
		} else {
			String[] paths = path.split("\\\\");
			//System.out.println("该目录最后一个" + paths[paths.length - 1]);
			List<Integer> id = new ArrayList<>();
			List<Node<T>> node = new ArrayList(Arrays.asList(nodes));
			int is = 0;
			for (Node<T> n : node) {
				is++;
				try {
					if (n.getData().toString() != null) {
						//System.out.println("开始匹配的名字：" + n.getData().toString());
						if (n.getData().toString()
								.equals(paths[paths.length - 1])) {
							id.add(n.getMyself());
						}
					}
				} catch (Exception e) {
					continue;
				}
				if (is == count)
					break;
			}
			if (id.size() == 1 && getPath(id.get(0)).equals(path)) {
				return id.get(0);
			} else if (id.size() > 1) {
				int finalId = 0;
				//System.out.println("开始需要匹配的路径" + path);
				for (int i : id) {
					//System.out.println("根据id获取路径"+getPath(i));
					if (getPath(i).equals(path)) {
						finalId = i;
						break;
					}
				}
				return finalId;
			} else {
				return -1;
			}
		}
	}

	@SuppressWarnings("unchecked")
	public String getPath(int i) {
		String path = "";
		Node<T> n = (Node<T>) nodes[i];
		if (n.getMyself() == 0) {
			path = n.getData().toString() + "\\";
		} else {
			while (n.getMyself() >= 0) {
				path = "\\" + n.getData().toString() + path;
				int next = n.getParent();
				if (n.getParent() == -1) {
					break;
				}
				n = (Node<T>) nodes[next];
			}
			path = path.substring(1);
		}
		return path;
	}

	public void praseJson() {

		// List<Node<T>> tran = new ArrayList(Arrays.asList(nodes));
		// String json = JSON.toJSONString(tran);
		// System.out.println(json);
		// System.out.println(tran.get(4).getMyself());
		// JSONArray jsonArray = JSONArray.parseArray(json);
		// List<Node> nodess = JSON.parseArray(json, Node.class);

		// System.out.println(((Node<T>) ob[5]).getData());

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Tree getTree() {
		Tree tree = new Tree();
		tree.setCount(this.count);
		tree.setNodes(new ArrayList(Arrays.asList(this.nodes)));
		tree.setSize(this.size);
		return tree;
	}

}
